#ifndef MY_TIME_H_
#define MY_TIME_H_

#include "esp_sntp.h"
#include <functional>
#include <string>
#include <vector>
#include <map>
#include <mutex>

#include "my_storage.h"
#include "my_linklist.h"

#define CONFIG_MAX_TASKS    16  // 最大支持闹钟数量
#define CONFIG_NAME_LEN     8
#define CONFIG_KEY_LEN      8

using RunCount  = int8_t;
struct Task {
    char            name[CONFIG_NAME_LEN];          // 任务名18446744072570831048
    char            callback_key[CONFIG_KEY_LEN];   // 回调键名
    std::string     callback_arg;                   // 回调参数
    time_t          start_run_time = 0;             // 开始运行时间（0表示现在）
    time_t          interval_sec;                   // 调度间隔
    RunCount        remain_runs = 1;                // 剩余工作次数

    Task() {
        name[0] = '\0';
        callback_key[0] = '\0';
    }
    Task(const char* task_name, const char* cb_key, const std::string& cb_arg, time_t start_time = 0, time_t interval = 0, RunCount count = 1)
        : callback_arg(cb_arg), start_run_time(start_time), interval_sec(interval), remain_runs(count)
    {
        if (task_name) {
            strncpy(name, task_name, CONFIG_NAME_LEN - 1);
            name[CONFIG_NAME_LEN - 1] = '\0';
        } else {
            name[0] = '\0';
        }
        if (cb_key) {
            strncpy(callback_key, cb_key, CONFIG_KEY_LEN - 1);
            callback_key[CONFIG_KEY_LEN - 1] = '\0';
        } else {
            callback_key[0] = '\0';
        }
        
        callback_arg = cb_arg;
        start_run_time = start_time;
        interval_sec = interval;
        remain_runs = count;
    }
    
    // 显式声明复制构造、赋值操作符、移动构造、移动操作符
    Task(const Task&) = default;
    Task& operator=(const Task&) = default;
    Task(Task&&) = default;
    Task& operator=(Task&&) = default;
};


class MyTime {
private:
    using AlarmCallback = std::function<void(const std::string& arg)>;
    enum TaskCronType {
        kYearly,        // 每年
        kMonthly,       // 每月
        kDaily,         // 每日
        kHourly,        // 每时
        kMinute,        // 每分钟
        kWeekly,        // 每周
        kCustom         // 自定义
    };
    
    struct TaskSaveInfo : Task {
        TaskCronType    type;                           // 任务类型
        
        TaskSaveInfo() : Task() {}
        TaskSaveInfo(const Task& task) : Task(task), type(kYearly){}

        TaskSaveInfo(const TaskSaveInfo&) = default;
        TaskSaveInfo& operator=(const TaskSaveInfo&) = default;
        TaskSaveInfo(TaskSaveInfo&&) = default;
        TaskSaveInfo& operator=(TaskSaveInfo&&) = default;
    };
    struct TaskCronInfo : Task {
        TaskCronType    type;                           // 任务类型
        bool            has_run = false;                // 是否已执行过

        explicit TaskCronInfo(const Task& task)
            : Task(task), type(kYearly), has_run(false){}
        explicit TaskCronInfo(const TaskSaveInfo& save_info) 
            : Task(save_info)
            , type(save_info.type)
            , has_run(false) {}

        TaskCronInfo(const TaskCronInfo&) = default;
        TaskCronInfo& operator=(const TaskCronInfo&) = default;
        TaskCronInfo(TaskCronInfo&&) = default;
        TaskCronInfo& operator=(TaskCronInfo&&) = default;
    };

public:
    MyTime(const MyTime&) = delete;
    MyTime& operator=(const MyTime&) = delete;
    static MyTime& GetInstance() {
        static MyTime time;
        return time;
    }
    // 获取当前秒数
    inline time_t GetTime() { 
        std::lock_guard<std::mutex> lock(mutex_);
        return now_; 
    }
    /// @brief 获取字符形式的时间
    /// @param result 保存时间的缓冲区
    /// @param len 缓冲区长度（长度需满足所需的时间格式）
    /// @param format 时间格式
    inline char* GetTime(char* result, size_t len, const char* format) {
        {
            std::lock_guard<std::mutex> lock(mutex_);
            strftime(result, len, format, &(current_time_));
        }
        return result;
    }

    inline bool RegisterCallback(const std::string& key, AlarmCallback cb) {
        std::lock_guard<std::mutex> lock(mutex_);
        return RegisterCallbackWithoutLock(key, cb);
    }

    // 添加周期性任务
    bool AddYearlyTask(Task&& info, AlarmCallback cb = nullptr, bool need_save = false);
    bool AddMonthlyTask(Task&& info, AlarmCallback cb = nullptr, bool need_save = false);
    bool AddDailyTask(Task&& info, AlarmCallback cb = nullptr, bool need_save = false);
    bool AddHourlyTask(Task&& info, AlarmCallback cb = nullptr, bool need_save = false);
    bool AddMinuteTask(Task&& info, AlarmCallback cb = nullptr, bool need_save = false);
    bool AddWeeklyTask(Task&& info, AlarmCallback cb = nullptr, bool need_save = false);
    bool AddCustomTask(Task&& info, AlarmCallback cb = nullptr, bool need_save = false);

    void DelTask(const std::string& task_name);             // 删除任务
    void ClearTaskList();                                   // 清空任务列表
    const Task* FindTask(const std::string& task_name);     // 查询任务

    static time_t MakeTime(int year, int month, int day, int hour, int minute);

private:
    MyTime();
    ~MyTime();

    bool RegisterCallbackWithoutLock(const std::string& key, AlarmCallback cb);
    bool AddTask(TaskCronInfo& task, AlarmCallback cb, bool need_save);
    bool SaveTask(const TaskCronInfo& task);
    void CallFunByKey(const std::string key, const std::string arg);
    void CheckAndExecuteTasks();
    inline bool ShouldExecuteTask(const TaskCronInfo& task);
    void ExecuteTask(TaskCronInfo& task);
    void ClearRunFlags();

    
    mutable std::mutex                      mutex_;
    time_t                                  now_;         
    struct tm                               current_time_;     
    TimerHandle_t                           timer_handle_;
    bool                                    flag_need_clean_;   // 是否有标志需要清除
    MyList<TaskCronInfo, CONFIG_MAX_TASKS>  cron_list_;         // 用于存储任务列表
    MyStorage<TaskSaveInfo>                 storage_;           // 永久存储实例，主要是用于恢复数据的
    std::map<std::string, AlarmCallback>    callback_map_;      // 关联回调函数的key-callback对   
};

#endif